package br.com.caim.viewcontroller.cadastro;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import br.com.caim.bo.entidade.Conta;
import br.com.caim.bo.entidade.Provedor;
import br.com.caim.bo.entidade.Usuario;
import br.com.caim.email.cadastro.ICadastroEmail;
import br.com.caim.email.cadastro.impl.CadastroEmail;
import br.com.caim.email.dao.Persistencia;
import br.com.caim.email.excecoes.negocio.LoginUsuarioJaCadastradoException;
import br.com.caim.email.excecoes.negocio.NenhumaContaEncontrada;
import br.com.caim.email.excecoes.negocio.ProvedorDeEmailInvalidoException;
import br.com.caim.viewcontroller.ActionPadrao;

public class CadastroAction extends ActionPadrao {
	private ICadastroEmail cadastro = new CadastroEmail();
	private static final String EMAIL_INVALIDO = "-1";
	private static final String FW_TELA_ERRO = "fwErro";
	private static final String FW_CADASTRO_CONTA = "fwCadastroConta";
	private static final String FW_CADASTRO_USUARIO = "fwCadastroUsuario";
	private static final String FW_CONFIRMACAO_CADASTRO = "fwConfirmacaoDados";
	
	public ActionForward redirecionarCadastroUsuario(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) {
		return mapping.findForward(FW_CADASTRO_USUARIO);
	}
	
	public ActionForward redirecionarCadastroConta(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) {
		request.getSession().setAttribute("cadastroNovaConta", true);
		
		return mapping.findForward(FW_CADASTRO_CONTA);
	}
	
	public ActionForward redirecionarConfirmacaoDados(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) throws ProvedorDeEmailInvalidoException {
		
		// Verifica se nenhuma outra conta foi cadadstrada
		ActionForward fwd = receberDadosConta(mapping, genericForm, request, response);
		
		return fwd;
	}
	
	public ActionForward receberDadosUsuario(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) {
		CadastroForm form = (CadastroForm) genericForm;
		Usuario user = new Usuario();
		
		String nomeUsuario = form.getNomeUsuario();
		String senhaUsuario = form.getPasswdUser();
		
		if(nomeUsuario != null && senhaUsuario != null) {
			user.setLogin(nomeUsuario);
			user.setSenha(senhaUsuario);
		} else {
			return mapping.findForward(FW_TELA_ERRO);
		}
		
		request.getSession().setAttribute("novoUsuario", user);
		
		return mapping.findForward(FW_CADASTRO_CONTA);
	}
	
	public ActionForward receberDadosConta(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) throws ProvedorDeEmailInvalidoException {
		Persistencia persist = new Persistencia();
		CadastroForm form = (CadastroForm) genericForm;
		Conta conta = new Conta();
		ActionForward fwd = mapping.findForward(FW_CONFIRMACAO_CADASTRO);
		
		String email = form.getEmail();
		String senhaConta = form.getPasswdConta();
		
		if((email != null && !email.equals("")) && (senhaConta != null && !senhaConta.equals(""))) {
			Usuario usuario = (Usuario) request.getSession().getAttribute("novoUsuario");
			
			if(usuario == null) {
				usuario = (Usuario) request.getSession().getAttribute("usuario");
			}
			
			if(usuario == null) {
				return mapping.findForward(FW_TELA_ERRO);
			}
			
			conta.setEnderecoEmail(email);
			conta.setSenha(senhaConta);
			conta.setUsuario(usuario);
			
			// Recupera o provedor
			String strProvedor = getNomeProvedorPeloEnderecoEmail(email);
			
			if(strProvedor.equals(EMAIL_INVALIDO)) {
				fwd = mapping.findForward(FW_TELA_ERRO);
			} else {
				Provedor provedor = persist.pesquisarProvedor(strProvedor);
				conta.setProvedor(provedor);
				
				Collection<Conta> contasExistentes = (Collection) request.getSession().getAttribute("contas");
				
				if(contasExistentes == null || contasExistentes.isEmpty()) {
					contasExistentes = new ArrayList<Conta>();
					contasExistentes.add(conta);
					request.getSession().setAttribute("contas", contasExistentes);
				} else {
					contasExistentes.add(conta);
					request.getSession().setAttribute("contas", contasExistentes);
				}
			}
		}
		
		return fwd;
	}
	
	public ActionForward cadastrarDados(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) throws LoginUsuarioJaCadastradoException {
		Usuario usuario = (Usuario) request.getSession().getAttribute("novoUsuario");
		Collection contas = (Collection) request.getSession().getAttribute("contas");
		
		try{
			// Cadastro do usuario
			cadastro.cadastroUsuario(usuario);
		} catch(Exception e) {
			String mensagem = e.getMessage();

			// Verifica se foi excecao de duplicidade
			if(mensagem.indexOf("Duplicate") > 0) {
				throw new LoginUsuarioJaCadastradoException();
			}
		}
		
		// Cadastro das contas
		cadastro.cadastroContas(contas);
		
		// Remove todos os atributos da sessao do usuario
		request.getSession().invalidate();
		
		return mapping.findForward("fwCadastroSucesso");
	}
	
	public ActionForward cadastrarContas(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) {
		
		Usuario usuarioSessao = (Usuario) request.getSession().getAttribute("usuario");
		Collection contas = (Collection) request.getSession().getAttribute("contas");
		
		Usuario user = new Usuario();
		user.setId(usuarioSessao.getId());

		// Cadastro das contas
		cadastro.cadastroContas(contas);
		
		return mapping.findForward("fwCadastroSucesso"); 
	}
	
	public String getNomeProvedorPeloEnderecoEmail(String email) {
		int indexInicio = email.indexOf("@") + 1;
		int indexFim = email.indexOf(".", indexInicio);
		
		if(indexInicio == -1) {
			return EMAIL_INVALIDO;
		}
		
		if(indexFim == -1) {
			indexFim = email.length();
		}
		
		return email.substring(indexInicio, indexFim);
	}
	
	public ActionForward apagarConta(ActionMapping mapping, ActionForm genericForm, 
			HttpServletRequest request, HttpServletResponse response) throws NenhumaContaEncontrada {
		Persistencia dao = new Persistencia();
		CadastroForm form = (CadastroForm) genericForm;
		
		String enderecoConta = form.getNomeContaRemover();
		Long idUsuario = ((Usuario) request.getSession().getAttribute("usuario")).getId();
		
		dao.removerObjeto(idUsuario.toString(), enderecoConta);
		
		// Atualiza a lista de contas do usuario
		Collection contas = dao.pesquisarContasUsuario(idUsuario.toString());
		request.getSession().setAttribute("contas", contas);
		
		return mapping.findForward(FW_CADASTRO_CONTA);
	}
}
